package com.keepers.repair.helper.bus;

import java.lang.ref.WeakReference;
import java.util.WeakHashMap;

import io.reactivex.Observable;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.subjects.PublishSubject;
import io.reactivex.subjects.Subject;

/**
 * auth aboom
 * date 2018/10/29
 */
public class RxBus {

    private final Subject<Object> bus;

    private static class RxBusHolder {
        private static final RxBus sInstance = new RxBus();
    }

    private RxBus() {
        bus = PublishSubject.create().toSerialized();
    }

    public static RxBus getDefault() {
        return RxBusHolder.sInstance;
    }

    /**
     * 提供一个事件
     */
    public void post(Object o) {
        bus.onNext(o);
    }

    /**
     * 根据传递的 eventType 类型返回特定类型(eventType)的 被观察者
     */
    public <T> Observable<T> toObservable(Class<T> eventType) {
        return bus.ofType(eventType);
    }

    /**
     * 缓存subscription。下一次toSingleObserverable时，检查类名：
     * 如果有该类名对应的Disposable，且没被注销掉，则注销。
     * 如果没有，则将新注册的subscription缓存到该HashMap中，键值是类名
     * Note:WeakReference:在下一次垃圾回收的时候，如果发现该引用可以被回收，则立即回收。
     */
    private WeakHashMap<String, WeakReference<Disposable>> singleDisposableWRs = new WeakHashMap<>();

    /**
     * 只能注册一次的事件流:缓存注册事件，下一次注册的时候，会把旧的注册事件注销掉。
     */
    public synchronized <T> Disposable toSingleObservable(Class<T> eventType, Consumer<T> onNext) {
        String className = eventType.getSimpleName();
        if (singleDisposableWRs.containsKey(className) && singleDisposableWRs.get(className) != null) {
            Disposable disposable = singleDisposableWRs.get(className).get();
            if (disposable != null && !disposable.isDisposed()) {
                disposable.dispose();
            }

        }
        Disposable disposable = bus.ofType(eventType).subscribe(onNext);
        singleDisposableWRs.put(className, new WeakReference<>(disposable));
        return disposable;
    }
}
